#include "Mesh.h"
#include "Paras.h"
//
namespace Euclid
{
	Mesh::Mesh()
		:	_mesh(0), _materials(0), _numMaterial(0), _xMaterialBuffer(0),
			_textures(0)
	{
		_device = Paras::getSingletonPtr()->_device;
	}

	Mesh::~Mesh()
	{
		for (unsigned int i = 0; i < _numMaterial; ++i)
		{
			if (_textures[i])
			{
				_textures[i]->Release();
				_textures[i] = 0;
			}
		}
		delete[] _textures;

		if (_mesh)
		{
			_mesh->Release();
			_mesh = 0;
		}
	}

	bool Mesh::createTeapot()
	{
		HRESULT hr;
		hr =D3DXCreateTeapot(_device, &_mesh, NULL);
		if (FAILED(hr))
		{
			return false;
		}

		//
		return true;
	}

	void Mesh::render()
	{
		//
		if (!_mesh)
		{
			return;
		}

		//
		HRESULT hr;
		for (unsigned int i = 0; i < _numMaterial; ++i)
		{
			//
			_device->SetMaterial(_materials + i);

			//
			_device->SetTexture(0, _textures[i]);

			//
			hr = _mesh->DrawSubset(i);
			if (FAILED(hr))
			{
				return;
			}
		}
	}
	bool Mesh::loadMeshFromX( std::string& file, unsigned long flag /*= D3DXMESH_SYSTEMMEM*/ )
	{
		//
		HRESULT hr;
		hr = D3DXLoadMeshFromX(file.c_str(), flag, _device, 0, &_xMaterialBuffer, 0, &_numMaterial, &_mesh);
		if (FAILED(hr))
		{
			return false;
		}

		//
		if (!_xMaterialBuffer)
		{
			return false;
		}

		//
		_materials = new D3DMATERIAL9[_numMaterial];

		//
		_textures = new LPDIRECT3DTEXTURE9[_numMaterial];

		//
		D3DXMATERIAL* mat = 0;
		mat = (D3DXMATERIAL*)_xMaterialBuffer->GetBufferPointer();

		//

		std::string tiger;
		Buddha::FileSystem::getSingletonPtr()->getDataDirectory(tiger);
		for(unsigned int i = 0; i < _numMaterial; ++i)
		{
			//
			_materials[i] = mat[i].MatD3D;
			_materials[i].Ambient = _materials[i].Diffuse;

			//
			tiger += "\\image\\";
			tiger += mat[i].pTextureFilename;
			hr = D3DXCreateTextureFromFile( _device, tiger.c_str(), &_textures[i] );
			if (FAILED(hr))
			{
				return false;
			}
		}

		//
		_xMaterialBuffer->Release();

		//
		return true;
	}

	bool Mesh::create()
	{
		return true;
	}

	void Mesh::destroy()
	{

	}

	void Mesh::preRender()
	{

	}

	void Mesh::postRender()
	{

	}
}
